from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
from flask_restful import reqparse, abort, \
    Api, Resource, fields, marshal_with

app = Flask(__name__)
api = Api(app)

HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'flask_sqlalchemy_demo'
USERNAME = 'root'
PASSWORD = 'root'

# dialect+driver://username:password@host:port/database
# DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8mb4".format(
#     username=USERNAME, password=PASSWORD, host=HOSTNAME, port=PORT, db=DATABASE)
DB_URI = "sqlite:///mycurd.db"

app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)


def abort_if_user_doesnt_exist(user_id):
    user = User.query.get(user_id)
    if user is None:
        abort(404, message="User {} doesn't exists".format(user_id))


class User(db.Model):
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(32), nullable=False)
    email = db.Column(db.String(64), nullable=False)

    def __repr__(self):
        return "<User(username: {})>".format(self.username)


class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(50), nullable=False)
    uid = db.Column(db.Integer, db.ForeignKey("user.id"))

    author = db.relationship("User", backref="articles")

# db.drop_all()
# db.create_all()

user = User(username="lavenliu", email="lcc@qq.com")
article1 = Article(title="Python高级编程")
article1.author = user
article2 = Article(title="Python从入门到放弃")
article2.author = user
db.session.add(article2)
db.session.commit()

users = User.query.order_by(User.id.desc()).all()
print(users)

for user in users:
    for article in user.articles:
        print(article)


class Users(Resource):

    resource_fileds = {
        'id': fields.Integer,
        'username': fields.String,
        'email': fields.String
    }

    @marshal_with(resource_fileds)
    def get(self, user_id):
        abort_if_user_doesnt_exist(user_id)
        user = User.query.get(user_id)
        return user

    def delete(self, user_id):
        abort_if_user_doesnt_exist(user_id)
        need_to_be_deleted_user = User.query.get(user_id)
        db.session.delete(need_to_be_deleted_user)
        db.session.commit()
        return '', 204

    @marshal_with(resource_fileds)
    def put(self, user_id):
        abort_if_user_doesnt_exist(user_id)
        user = User.query.get(user_id)
        username = request.json['username']
        email = request.json['email']
        user.username = username
        user.email = email
        db.session.commit()
        return user


class UsersList(Resource):

    resource_fileds = {
        'id': fields.Integer,
        'username': fields.String,
        'email': fields.String
    }

    @marshal_with(resource_fileds)
    def get(self):
        # users = User.query.order_by(User.id.desc()).all()
        users = User.query.all()
        return users

    @marshal_with(resource_fileds)
    def post(self):
        username = request.json['username']
        email = request.json['email']

        new_user = User(username=username, email=email)

        db.session.add(new_user)
        db.session.commit()

        return new_user

api.add_resource(Users, '/users/<user_id>')
api.add_resource(UsersList, '/users/')


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()
